25#include <Eigen/Geometry>
75inline Matrix<T, 2, 2>
exp(
const T theta)
77 return Rotation2D<T>(theta).matrix();
87inline Matrix<T, 2, 2>
skew(
const T& t)
89 return (Matrix<T, 2, 2>() << (T)0, -t, t, (T)0).finished();
95inline Matrix<typename D::Scalar, 2, 1>
skewed(
const MatrixBase<D>& t)
97 return Matrix<typename D::Scalar, 2, 1>(-t(1), t(0));
112 T sin_half =
sin(theta / T(2.0));
113 s =
sin(theta) / theta;
114 c_1 = T(2.0) * sin_half * sin_half / theta;
119 s = T(1.0) - theta * theta / T(6.0);
120 c_1 = theta / T(2.0);
123 return (Matrix<T, 2, 2>() << s, -c_1, c_1, s).finished();
135 a = (theta / T(2.0)) /
tan(theta / T(2.0));
137 a = T(1.0) - theta * theta / T(12.0);
139 return (Matrix<T, 2, 2>() << a, theta / T(2.0), -theta / T(2.0), a).finished();
144template <
class D,
typename T>
145inline Matrix<T, 2, 1>
J_Vp_theta(
const MatrixBase<D>& p,
const T theta)
157 if (
abs(theta) > T(1e-2))
161 T theta2 = theta * theta;
162 ds = (theta * c_th - s_th) / theta2;
163 dc_1 = (theta * s_th - T(1.0) + c_th) / theta2;
167 T theta2 = theta * theta;
168 ds = theta * (-T(1. / 3.) + theta2 * (T(1. / 30.) - theta2 / T(840.)));
169 dc_1 = T(0.5) + theta2 * (-T(1. / 8.) + theta2 * (T(1. / 144.) - theta2 / T(5760.)));
172 return Matrix<T, 2, 1>(ds * p(0) - dc_1 * p(1), dc_1 * p(0) + ds * p(1));
181inline Matrix<typename D::Scalar, 3, 3>
jac_SE2_left(
const MatrixBase<D>& tangent)
184 typedef typename D::Scalar T;
188 T theta = tangent(2);
197 if (
abs(theta) > T(1e-2))
199 T sin_half =
sin(theta / T(2.0));
200 T theta2 = theta * theta;
201 A = T(2.0) * sin_half * sin_half / theta2;
202 B = (theta -
sin(theta)) / theta2;
206 T theta2 = theta * theta;
207 A = T(0.5) + theta2 * (-T(1. / 24.) + theta2 / T(720.));
208 B = theta * (T(1. / 6.) + theta2 * (-T(1. / 120.) + theta2 / T(5040.)));
212 Jl.template topLeftCorner<2, 2>() =
V_helper(theta);
213 Jl(0, 2) = x * B + y * A;
214 Jl(1, 2) = -x * A + y * B;
224inline Matrix<typename D::Scalar, 3, 3>
jac_SE2_right(
const MatrixBase<D>& tangent)
226 return jac_SE2_left(Matrix<typename D::Scalar, 3, 1>(-tangent));
234 typedef typename D::Scalar T;
239 Matrix<T, 3, 3> Jl_inv = Matrix<T, 3, 3>::Identity();
240 Jl_inv.template topLeftCorner<2, 2>() = A_inv;
241 Jl_inv.template topRightCorner<2, 1>() = -A_inv * Jl.template topRightCorner<2, 1>();
257inline void identity(MatrixBase<D>& p,
typename D::Scalar& o)
261 o =
typename D::Scalar(0);
264template <
typename D1,
typename D2>
265inline void identity(MatrixBase<D1>& p, MatrixBase<D2>& o)
276 Map<Matrix<typename D::Scalar, 2, 1>> p(&d(0));
280template <
typename T =
double>
306template <
typename D1,
typename D2>
307inline void inverse(
const MatrixBase<D1>& p,
const typename D1::Scalar& o, MatrixBase<D2>& ip,
typename D2::Scalar& io)
316template <
typename D1,
typename D2,
typename D3,
typename D4>
317inline void inverse(
const MatrixBase<D1>& p,
const MatrixBase<D2>& o, MatrixBase<D3>& ip, MatrixBase<D4>& io)
325template <
typename D1,
typename D2>
326inline void inverse(
const MatrixBase<D1>& d, MatrixBase<D2>&
id)
331 const auto p = d.template head<2>();
332 Map<Matrix<typename D2::Scalar, 2, 1>> ip(&
id(0));
338inline Matrix<typename D::Scalar, 3, 1>
inverse(
const MatrixBase<D>& d)
340 Matrix<typename D::Scalar, 3, 1> id;
349 inverse(v.at(
'P'), v.at(
'O'), c[
'P'], c[
'O']);
362template <
typename D1,
typename D2,
typename D3>
364 const typename D1::Scalar& o1,
365 const MatrixBase<D2>& p2,
366 const typename D2::Scalar& o2,
368 typename D3::Scalar& oc)
381template <
typename D1,
typename D2,
typename D4,
typename D5,
typename D7,
typename D8>
383 const MatrixBase<D2>& o1,
384 const MatrixBase<D4>& p2,
385 const MatrixBase<D5>& o2,
393 compose(p1, o1(0), p2, o2(0), pc, oc(0));
396template <
class D1,
class D2,
class D3>
397inline void compose(
const MatrixBase<D1>& _delta1,
398 const MatrixBase<D2>& _delta2,
399 MatrixBase<D3>& _delta1_compose_delta2)
405 const auto p1 = _delta1.template head<2>();
406 const auto p2 = _delta2.template head<2>();
407 Map<Matrix<typename D3::Scalar, 2, 1>> pc(&_delta1_compose_delta2(0));
409 compose(p1, _delta1(2), p2, _delta2(2), pc, _delta1_compose_delta2(2));
412template <
class D1,
class D2>
413inline Matrix<typename D1::Scalar, 3, 1>
compose(
const MatrixBase<D1>& _delta1,
const MatrixBase<D2>& _delta2)
415 Matrix<typename D1::Scalar, 3, 1> delta1_compose_delta2;
416 compose(_delta1, _delta2, delta1_compose_delta2);
417 return delta1_compose_delta2;
420template <
class D1,
class D2,
class D3,
class D4,
class D5>
421inline void compose(
const MatrixBase<D1>& _delta1,
422 const MatrixBase<D2>& _delta2,
423 MatrixBase<D3>& _delta1_compose_delta2,
424 MatrixBase<D4>& _J_compose_delta1,
425 MatrixBase<D5>& _J_compose_delta2)
433 typedef typename D1::Scalar T;
435 Matrix<T, 2, 2> R1 =
SO2::exp(T(_delta1(2)));
464 _J_compose_delta1.setIdentity();
465 _J_compose_delta1.template block<2, 1>(0, 2) = R1 *
skewed(_delta2.template head<2>());
467 _J_compose_delta2.setIdentity(3, 3);
468 _J_compose_delta2.template block<2, 2>(0, 0) = R1;
472 compose(_delta1, _delta2, _delta1_compose_delta2);
479 compose(_x1.at(
'P'), _x1.at(
'O'), _x2.at(
'P'), _x2.at(
'O'), _c[
'P'], _c[
'O']);
532template <
typename D1,
typename D2,
typename D3>
534 const typename D1::Scalar& o1,
535 const MatrixBase<D2>& p2,
536 const typename D2::Scalar& o2,
538 typename D3::Scalar& o12)
545 o12 =
pi2pi(o2 - o1);
548template <
typename D1,
typename D2,
typename D4,
typename D5,
typename D7,
typename D8>
550 const MatrixBase<D2>& o1,
551 const MatrixBase<D4>& p2,
552 const MatrixBase<D5>& o2,
560 between(p1, o1(0), p2, o2(0), p12, o12(0));
563template <
typename D1,
typename D2,
typename D3>
564inline void between(
const MatrixBase<D1>& d1,
const MatrixBase<D2>& d2, MatrixBase<D3>& d12)
570 const auto p1 = d1.template head<2>();
571 const auto p2 = d2.template head<2>();
572 Map<Matrix<typename D3::Scalar, 2, 1>> p12(&d12(0));
574 between(p1, d1(2), p2, d2(2), p12, d12(2));
577template <
typename D1,
typename D2>
578inline Matrix<typename D1::Scalar, 3, 1>
between(
const MatrixBase<D1>& d1,
const MatrixBase<D2>& d2)
580 Matrix<typename D1::Scalar, 3, 1> d12;
589 between(x1.at(
'P'), x1.at(
'O'), x2.at(
'P'), x2.at(
'O'), x12[
'P'], x12[
'O']);
602template <
typename D1,
typename D2>
603inline void exp(
const MatrixBase<D1>& rho,
const typename D1::Scalar& theta, MatrixBase<D2>& p,
typename D2::Scalar& o)
613template <
typename D1,
typename D2,
typename D3,
typename D4>
614inline void exp(
const MatrixBase<D1>& rho,
const MatrixBase<D2>& theta, MatrixBase<D3>& p, MatrixBase<D4>& o)
619 exp(rho, theta(0), p, o(0));
622template <
class D1,
class D2>
623inline void exp(
const MatrixBase<D1>& _tau, MatrixBase<D2>& _delta)
628 const auto rho = _tau.template head<2>();
629 Map<Matrix<typename D2::Scalar, 2, 1>> p(&_delta(0));
631 exp(rho, _tau(2), p, _delta(2));
635inline Matrix<typename D::Scalar, 3, 1>
exp(
const MatrixBase<D>& _tau)
637 Matrix<typename D::Scalar, 3, 1> _delta;
642template <
class D1,
class D2,
class D3>
643inline void exp(
const MatrixBase<D1>& _tau, MatrixBase<D2>& _delta, MatrixBase<D3>& _J_delta_tau)
649 typedef typename D1::Scalar T;
651 Matrix<T, 3, 1> tau = _tau;
657 _J_delta_tau.template topLeftCorner<2, 2>() =
V_helper(tau(2));
658 _J_delta_tau.template topRightCorner<2, 1>() =
J_Vp_theta(tau.template head<2>(), tau(2));
659 _J_delta_tau.template bottomRows<1>() << T(0), T(0), T(1);
666 _delta[
'P'].resize(2);
667 _delta[
'O'].resize(1);
668 exp(_tau.at(
'P'), _tau.at(
'O'), _delta[
'P'], _delta[
'O']);
702template <
typename D1,
typename D2>
703inline void log(
const MatrixBase<D1>& p,
const typename D1::Scalar& o, MatrixBase<D2>& rho,
typename D2::Scalar& theta)
708 typename D1::Scalar th =
pi2pi(o);
713template <
typename D1,
typename D2,
typename D3,
typename D4>
714inline void log(
const MatrixBase<D1>& p,
const MatrixBase<D2>& o, MatrixBase<D3>& rho, MatrixBase<D4>& theta)
719 log(p, o(0), rho, theta(0));
722template <
class D1,
class D2>
723inline void log(
const MatrixBase<D1>& _delta, MatrixBase<D2>& _tau)
728 const auto p = _delta.template head<2>();
729 Map<Matrix<typename D2::Scalar, 2, 1>> rho(&_tau(0));
731 log(p, _delta(2), rho, _tau(2));
735inline Matrix<typename D::Scalar, 3, 1>
log(
const MatrixBase<D>& _delta)
737 Matrix<typename D::Scalar, 3, 1> _tau;
742template <
class D1,
class D2,
class D3>
743inline void log(
const MatrixBase<D1>& _delta, MatrixBase<D2>& _tau, MatrixBase<D3>& _J_tau_delta)
749 typedef typename D1::Scalar T;
757 _J_tau_delta.template topLeftCorner<2, 2>() = V_inv;
758 _J_tau_delta.template topRightCorner<2, 1>() = -V_inv *
J_Vp_theta(tau.template head<2>(), tau(2));
759 _J_tau_delta.template bottomRows<1>() << T(0), T(0), T(1);
768 log(_delta.at(
'P'), _delta.at(
'O'), _tau[
'P'], _tau[
'O']);
781template <
typename D1,
typename D2,
typename D3>
782inline void plus(
const MatrixBase<D1>& p1,
783 const typename D1::Scalar& o1,
784 const MatrixBase<D2>& p2,
785 const typename D2::Scalar& o2,
786 MatrixBase<D3>& plus_p,
787 typename D3::Scalar& plus_o)
794 plus_o =
pi2pi(o1 + o2);
797template <
typename D1,
typename D2,
typename D4,
typename D5,
typename D7,
typename D8>
798inline void plus(
const MatrixBase<D1>& p1,
799 const MatrixBase<D2>& o1,
800 const MatrixBase<D4>& p2,
801 const MatrixBase<D5>& o2,
802 MatrixBase<D7>& plus_p,
803 MatrixBase<D8>& plus_o)
809 plus(p1, o1(0), p2, o2(0), plus_p, plus_o(0));
812template <
typename D1,
typename D2,
typename D3>
813inline void plus(
const MatrixBase<D1>& d1,
const MatrixBase<D2>& d2, MatrixBase<D3>& d_plus)
819 const auto p1 = d1.template head<2>();
820 const auto p2 = d2.template head<2>();
821 Map<Matrix<typename D3::Scalar, 2, 1>> p_p(&d_plus(0));
823 plus(p1, d1(2), p2, d2(2), p_p, d_plus(2));
826template <
typename D1,
typename D2>
827inline Matrix<typename D1::Scalar, 3, 1>
plus(
const MatrixBase<D1>& d1,
const MatrixBase<D2>& d2)
829 Matrix<typename D1::Scalar, 3, 1> d_plus;
830 plus(d1, d2, d_plus);
838 plus(x.at(
'P'), x.at(
'O'), tau.at(
'P'), tau.at(
'O'), res[
'P'], res[
'O']);
851template <
typename D1,
typename D2,
typename D3>
852inline void minus(
const MatrixBase<D1>& p1,
853 const typename D1::Scalar& o1,
854 const MatrixBase<D2>& p2,
855 const typename D2::Scalar& o2,
857 typename D3::Scalar& od)
867template <
typename D1,
typename D2,
typename D3>
868inline void minus(
const MatrixBase<D1>& p1,
869 const typename D1::Scalar& o1,
870 const MatrixBase<D2>& p2,
871 const typename D2::Scalar& o2,
873 typename D3::Scalar& od,
874 typename D3::Scalar& J_do_o1,
875 typename D3::Scalar& J_do_o2)
877 minus(p1, o1, p2, o2, pd, od);
879 J_do_o1 =
typename D3::Scalar(-1);
880 J_do_o2 =
typename D3::Scalar(1);
883template <
typename D1,
typename D2,
typename D4,
typename D5,
typename D7,
typename D8>
884inline void minus(
const MatrixBase<D1>& p1,
885 const MatrixBase<D2>& o1,
886 const MatrixBase<D4>& p2,
887 const MatrixBase<D5>& o2,
895 minus(p1, o1(0), p2, o2(0), pd, od(0));
898template <
typename D1,
typename D2,
typename D3>
899inline void minus(
const MatrixBase<D1>& d1,
const MatrixBase<D2>& d2, MatrixBase<D3>& err)
905 const auto p1 = d1.template head<2>();
906 const auto p2 = d2.template head<2>();
907 Map<Matrix<typename D3::Scalar, 2, 1>> pd(&err(0));
909 minus(p1, d1(2), p2, d2(2), pd, err(2));
912template <
typename D1,
typename D2,
typename D3,
typename D4,
typename D5>
913inline void minus(
const MatrixBase<D1>& d1,
914 const MatrixBase<D2>& d2,
916 MatrixBase<D4>& J_diff_d1,
917 MatrixBase<D5>& J_diff_d2)
925 J_diff_d1 = -Matrix<typename D4::Scalar, 3, 3>::Identity();
926 J_diff_d2 = Matrix<typename D5::Scalar, 3, 3>::Identity();
929template <
typename D1,
typename D2>
930inline Matrix<typename D1::Scalar, 3, 1>
minus(
const MatrixBase<D1>& d1,
const MatrixBase<D2>& d2)
932 Matrix<typename D1::Scalar, 3, 1> ret;
941 minus(x1.at(
'P'), x1.at(
'O'), x2.at(
'P'), x2.at(
'O'), res[
'P'], res[
'O']);
954template <
typename D1,
typename D2,
typename D3>
956 const MatrixBase<D2>& d2,
957 const typename D1::Scalar& t,
964 Matrix<typename D1::Scalar, 3, 1> dd =
between(d1, d2);
966 Matrix<typename D1::Scalar, 3, 1> tau = t *
log(dd);
971template <
typename D1,
typename D2>
972inline Matrix<typename D1::Scalar, 3, 1>
interpolate(
const MatrixBase<D1>& d1,
973 const MatrixBase<D2>& d2,
974 const typename D1::Scalar& t)
976 Matrix<typename D1::Scalar, 3, 1> ret;
999template <
typename D1,
typename D2>
1000inline void toSE2(
const MatrixBase<D1>& pose, MatrixBase<D2>& SE2)
1005 typedef typename D1::Scalar T;
1007 SE2.template block<2, 1>(0, 2) = pose.template head<2>();
1008 SE2.template block<2, 2>(0, 0) =
SO2::exp(T(pose(2)));
1009 SE2.template block<1, 2>(2, 0).setZero();
1013template <
typename D>
1014inline Matrix<typename D::Scalar, 3, 3>
toSE2(
const MatrixBase<D>& pose)
1016 Matrix<typename D::Scalar, 3, 3> SE2;
Definition: vector_composite.h:27
Namespace extending Eigen definitions.
Definition: wolf.h:94
const double EPS
Definition: wolf.h:74
Matrix< typename D::Scalar, 3, 3 > jac_SE2_left(const MatrixBase< D > &tangent)
Left Jacobian of SE(2), with tangent = [rho, theta]. See [1] eq. 164.
Definition: SE2.h:181
void identity(MatrixBase< D > &p, typename D::Scalar &o)
Definition: SE2.h:257
Matrix< T, 2, 2 > V_helper(const T theta)
V(theta) matrix, so that exp([rho, theta]) = [V(theta) * rho, theta]. See [1] eq. 158.
Definition: SE2.h:103
void exp(const MatrixBase< D1 > &rho, const typename D1::Scalar &theta, MatrixBase< D2 > &p, typename D2::Scalar &o)
Definition: SE2.h:603
void compose(const MatrixBase< D1 > &p1, const typename D1::Scalar &o1, const MatrixBase< D2 > &p2, const typename D2::Scalar &o2, MatrixBase< D3 > &pc, typename D3::Scalar &oc)
Definition: SE2.h:363
Matrix< typename D::Scalar, 3, 3 > jac_SE2_right_inv(const MatrixBase< D > &tangent)
Inverse of the right Jacobian of SE(2), with tangent = [rho, theta].
Definition: SE2.h:248
void log(const MatrixBase< D1 > &p, const typename D1::Scalar &o, MatrixBase< D2 > &rho, typename D2::Scalar &theta)
Definition: SE2.h:703
void between(const MatrixBase< D1 > &p1, const typename D1::Scalar &o1, const MatrixBase< D2 > &p2, const typename D2::Scalar &o2, MatrixBase< D3 > &p12, typename D3::Scalar &o12)
Definition: SE2.h:533
void toSE2(const MatrixBase< D1 > &pose, MatrixBase< D2 > &SE2)
Definition: SE2.h:1000
Matrix< typename D::Scalar, 3, 3 > jac_SE2_right(const MatrixBase< D > &tangent)
Right Jacobian of SE(2), with tangent = [rho, theta]. See [1] eq. 163.
Definition: SE2.h:224
void minus(const MatrixBase< D1 > &p1, const typename D1::Scalar &o1, const MatrixBase< D2 > &p2, const typename D2::Scalar &o2, MatrixBase< D3 > &pd, typename D3::Scalar &od)
Definition: SE2.h:852
void interpolate(const MatrixBase< D1 > &d1, const MatrixBase< D2 > &d2, const typename D1::Scalar &t, MatrixBase< D3 > &ret)
Definition: SE2.h:955
Matrix< typename D::Scalar, 3, 3 > jac_SE2_left_inv(const MatrixBase< D > &tangent)
Inverse of the left Jacobian of SE(2), with tangent = [rho, theta].
Definition: SE2.h:232
void inverse(const MatrixBase< D1 > &p, const typename D1::Scalar &o, MatrixBase< D2 > &ip, typename D2::Scalar &io)
Definition: SE2.h:307
Matrix< T, 2, 2 > skew(const T &t)
Definition: SE2.h:87
VectorComposite identityComposite()
Definition: SE2.h:296
Matrix< typename D::Scalar, 2, 1 > skewed(const MatrixBase< D > &t)
Compute [1]_x * t = (-t.y ; t.x)
Definition: SE2.h:95
Matrix< T, 2, 1 > J_Vp_theta(const MatrixBase< D > &p, const T theta)
Jacobian of V(theta)*p wrt theta.
Definition: SE2.h:145
Matrix< T, 2, 2 > V_inv_helper(const T theta)
Inverse of V(theta), so that log([p, theta]) = [V(theta).inv * p, theta].
Definition: SE2.h:129
void plus(const MatrixBase< D1 > &p1, const typename D1::Scalar &o1, const MatrixBase< D2 > &p2, const typename D2::Scalar &o2, MatrixBase< D3 > &plus_p, typename D3::Scalar &plus_o)
Definition: SE2.h:782
Matrix< T, 2, 2 > exp(const T theta)
Definition: SE2.h:75
Jet< T, N > abs(const Jet< T, N > &f)
Definition: jet.h:531
Jet< T, N > sin(const Jet< T, N > &f)
Definition: jet.h:641
Jet< T, N > tan(const Jet< T, N > &f)
Definition: jet.h:656
Jet< T, N > cos(const Jet< T, N > &f)
Definition: jet.h:626
Definition: capture_base.h:23
T pi2pi(const T &_angle)
Return angle between -pi and pi This implementation uses std::remainder which makes it incompatible f...
Definition: rotations.h:34
static void check(const Eigen::MatrixBase< T > &t)
Assert matrix size dynamically or statically.
Definition: eigen_assert.h:93